<?php
declare (strict_types = 1);

namespace app\product\service;

use app\auth\common\util\ApiUtil;
use app\product\model\ProductAttrVariousModel;
use app\product\model\ProductModel;
use think\facade\Validate;

class ProductService extends BaseService
{
    public function __construct(ProductModel $productModel,
                                ProductAttrNameService $productAttrNameService,
                                ProductAttrValueService $productAttrValueService,
                                ProductAttrVariousService $productAttrVariousService,
                                ProductAttrVariousValueLinkService $productAttrVariousValueLinkService,
                                SupplierService $supplierService,
                                CategoryService $categoryService,
                                CategoryLinkService $categoryLinkService)
    {
        $this->productModel = $productModel;
        $this->productAttrNameService = $productAttrNameService;
        $this->productAttrValueService = $productAttrValueService;
        $this->productAttrVariousService = $productAttrVariousService;
        $this->productAttrVariousValueLinkService = $productAttrVariousValueLinkService;
        $this->supplierService = $supplierService;
        $this->categoryService = $categoryService;
        $this->categoryLinkService = $categoryLinkService;
    }

    public function model(){
        return $this->productModel;
    }

    public function list(array $where = [] , array $limit = [], array $sort= []){
        $limit = check_limit($limit);
        $sort = check_sort($sort);
        $model = $this->productModel;
        if(isset($where['product_id'])){
            $model = $model->whereIn('id',$where['product_id']);
            unset($where['product_id']);
        }
        $model = $model->where($where)->limit($limit['page'],$limit['pagesize'])->order($sort[0],$sort[1]);
        return $model->select();
    }

    public function select(array $where = [],$field = ['*']){
        $sort = check_sort();
        return $this->productModel->field($field)->where($where)->order($sort[0],$sort[1])->select();
    }

    public function count(array $where = []){
        $model = $this->productModel;
        if(isset($where['product_id'])){
            $model = $model->whereIn('id',$where['product_id']);
            unset($where['product_id']);
        }
        $model = $model->where($where);
        return $model->count();
    }

    public function find(array $where = []){
        $find = $this->productModel->where($where)->find();
        if(!empty($find)){ // 压入变体
            $find = $find->toarray();
            $find['variants'] = $this->getSkus($find['id']);
        }
        return $find;
    }

    public function insertGetId(array $data = []){
        return $this->productModel->insertGetId($data);
    }

    public function update(array $where = [],array $data = []){
        return $this->productModel->where($where)->update($data);
    }

    public function delete(array $whereIn = []){
        return $this->productModel->whereIn($whereIn[0],$whereIn[1])->delete();
    }

    public function search(array $params = []){
        $where = array();
        $where = time_search($params,'ptime',$where);
        $name = !empty($params['name'])?trim($params['name']):'';
        $sku = !empty($params['child_sku'])?trim($params['child_sku']):'';
        $upload_uid = !empty($params['upload_uid'])?intval($params['upload_uid']):0;
        $category_id = !empty($params['category_id'])?trim($params['category_id']):'';
        $product_grade = !empty($params['product_grade'])?trim($params['product_grade']):'';
        if(!empty($name)) $where[] = ['name', 'like', '%'.$name.'%'];
        if(!empty($upload_uid)) $where[] = ['upload_uid', '=', $upload_uid ];
        if(!empty($product_grade)) $where[] = ['product_grade', '=', $product_grade ];
        // 搜索分类
        if(!empty($category_id)) {
            $in_top = $this->categoryService->select(['pid'=>0],'id')->column('id');
            $category = explode(',', $category_id);
            $cid_arr = [];
            foreach ($category as $k => $v) {
                $cid_arr[] = $v;
                // 如果有顶级分类则查询该分类下的所有子分类
                if(!in_array($v, $in_top)) continue;
                $child_cate = $this->categoryService->select(['pid'=>$v])->toArray();
                // 查询二级分类下的子分类
                if(!$child_cate) continue;
                foreach ($child_cate as $k2 => $v2) {
                    $cid_arr[] = $v2['id'];
                    $two_level_cate = $this->categoryService->select(['pid'=> $v2['id'] ])->toArray();
                    if($two_level_cate) foreach ($two_level_cate as $k3 => $v3) $cid_arr[] = $v3['id'];
                }
            }
            // 去多分类表获取对应的产品ID 来作为搜索条件
            $multiple_cate = $this->categoryLinkService->select([],['product_id'],['cate_id',$cid_arr])->column('product_id');
            $where['product_id'] = array_unique($multiple_cate);
        }
        // 搜索子SKU + 主sku
        if(!empty($sku)) {
            $master_sku = $this->productModel->where([['sku', 'like', '%'.$sku.'%' ]])->count();
            if(!empty($master_sku)){
                $where[] = ['sku', 'like', '%'.$sku.'%'];
            } else{// 查找子SKU的产品ID
                $skuIds = $this->productAttrVariousService->select([['chlid_sku', 'like', '%'.$sku.'%' ]])->column('product_id');
                if(!empty($where['product_id'])) {// 合并子SKU + 分类，并去重
                    $where['product_id'] = array_keys(array_flip($skuIds)+array_flip($where['product_id']));
                }else{
                    $where['product_id'] = $skuIds;
                }
            }
        }
        return $where;
    }

    public function verify(array $params = [],int $id = 0){
        $tableName = $this->model()->getTable();
        $validate = Validate::rule([
            'name'=>'require|chsDash|unique:'.$tableName.',name,'.$id,
            'image' => 'require',
            'category_id' => 'require',
            'crowd' => 'require',
            'purchase_price' => 'require|float',
            'product_grade' => 'require',
            'source_link' => 'require|url',
            'sku' => 'require|unique:'.$tableName.',sku,'.$id,
            'remark' => 'max:255',
        ]);
        if(!$validate->check($params)) return $validate->getError();
        $data = array();
        $data['name'] = $params['name'];
        $data['image'] = $params['image'];
        $data['sku'] = trim($params['sku']);
        $data['category_id'] = $params['category_id'];
        $data['crowd'] = $params['crowd'];
        $data['manufacturer_number'] = !empty($params['manufacturer_number'])?strip_tags($params['manufacturer_number']):'';
        $data['purchase_price'] = $params['purchase_price'];
        $data['freight'] = !empty($params['freight'])?strip_tags($params['freight']):0;
        $data['weight'] = $params['weight'];
        $data['moq'] = !empty($params['moq'])?intval($params['moq']):0;
        $data['recommend_reason'] = !empty($params['recommend_reason'])?strip_tags($params['recommend_reason']):'';
        $data['product_grade'] = product_grade($params['product_grade']);
        $data['competing_product_link'] = !empty($params['competing_product_link'])?strip_tags($params['competing_product_link']):'';
        $data['source_link'] = $params['source_link'];
        $data['remark'] = !empty($params['remark'])?strip_tags($params['remark']):'';
        $data['up_shopify'] = !empty($params['up_shopify'])?intval($params['up_shopify']):0;
        $data['up_ueeshop'] = !empty($params['up_ueeshop'])?intval($params['up_ueeshop']):0;
        $data['up_lazala'] = !empty($params['up_lazala'])?intval($params['up_lazala']):0;
        $data['charged'] = !empty($params['charged'])?intval($params['charged']):0;
        $data['invoice_amount'] = !empty($params['invoice_amount'])?floatval($params['invoice_amount']):0;
        $data['invoice_pcs'] = !empty($params['invoice_pcs'])?floatval($params['invoice_pcs']):0;
        $data['invoice_title'] = !empty($params['invoice_title'])?strip_tags($params['invoice_title']):'';
        $data['supplier_id'] = !empty($params['supplier_id'])?intval($params['supplier_id']):0;
        if(empty($id)){
            $data['create_time'] = $data['ptime'] = time();
            $data['upload_uid'] = request()->admin_id;
        }else{
            $data['update_time'] = time();
            $data['mender'] = request()->admin_id;
        }
        return $data;
    }

    /**
     * [getSkus 获取变体属性]
     * @param  int|integer $pid   [产品ID]
     * @param  array      $del_fields [传的这个字段是剔除的意思]
     * @return [type]             [description]
     */
    function getSkus(int $pid=0, array $del_fields = []){
        $variants = array();
        if(empty($pid)) return $variants;
        $variant = $this->productAttrVariousService->select(['product_id'=>$pid]);
        foreach ($variant as $k => $v) {
            $variants[$k]['id'] = $v->id; // 子sku表Id
            $variants[$k]['u_sku'] = $v->chlid_sku;
            if(!in_array('price', $del_fields)) $variants[$k]['price'] = $v->price;
            $variants[$k]['supplier_id'] = $v->supplier_id;
            $variants[$k]['weight'] = $v->weight;
            $variants[$k]['image_path'] = $v->image_path;
            $supplier_name = $this->supplierService->value(['id'=>$v->supplier_id],'name');
            if(!in_array('supplier_name', $del_fields)) $variants[$k]['supplier_name'] = !empty($supplier_name)?$supplier_name:'';
            $attr = $this->productAttrValueService->select([],['*'],['id',explode(',', $v->attr_value_id)]);
            $attrArr = $attr->toArray();
            $last_names = $attr->column('id');
            array_multisort($last_names,SORT_ASC,$attrArr); // Array sort
            foreach ($attrArr as $v1) $variants[$k]['attribute'][$v1['attr_name'][0]['attr_name']] = $v1['attr_value'];
            $variants[$k]['attribute'] = json_encode($variants[$k]['attribute']);
        }
        return $variants;
    }

    /**
     * [addSkus 添加变体属性]
     * @param string|integer $pid  [产品ID]
     * @param string         $skus [json变体字符串]
     * @param string         $master_sku [主SKU]
     */
    public function addSkus(int $pid=0 , string $skus = '' , string $master_sku = ''){
        if(empty($pid) || empty($skus)) ApiUtil::abort('产品ID和变体不可以为空');
        if(empty($master_sku)) ApiUtil::abort('产品主SKU不可以为空');
        $variants = json_decode($skus,true);
        // 检查属性是否为数组
        foreach ($variants as &$attr) {
            if(empty($attr['supplier_id'])) ApiUtil::abort('子供应商ID不能为空');
            if(empty($attr['weight'])) ApiUtil::abort('子重量不能为空');
            if(empty($attr['image_path'])) ApiUtil::abort('子图片路径不能为空');
            if(!is_array($attr['variant'])) $attr['variant'] = json_decode($attr['variant'],true);
        }
        $names = array_keys($variants[0]['variant']);
        $attr_names = $attr_values = $attr_skus = $attr_various = $attr_value_link = array();
        $chlid_sku_suffix = '';
        foreach ($names as $key => $value) {
            $attr_names['attr_name'] = $value;
            $attr_names['product_id'] = $pid;
            $this->productAttrNameService->insertGetId($attr_names); // Insert attribute name
        }
        foreach ($variants as $k => $v) {
            foreach ($v['variant'] as $k1 => $v1) {
                // 获取属性名ID
                $attrNid = $this->productAttrNameService->value(['attr_name'=>$k1,'product_id'=>$pid],'id');
                // Get attribute value id
                $attrVid = $this->productAttrValueService->value(['attr_value'=>$v1,'product_id'=>$pid],'id');
                if($attrVid){
                    $attr_value_link[$k][] = $attrVid;
                }else{
                    $attr_values['attr_name_id'] = $attrNid;
                    $attr_values['product_id'] = $pid;
                    $attr_values['attr_value'] = $v1;
                    $attr_value_link[$k][] = $this->productAttrValueService->insertGetId($attr_values);
                }
                $chlid_sku_suffix .= '-'.$v1;
            }
            // 子SKU规则： 按照主sku-属性1-属性2 【 hd1002196-红色-XL 】
            $attr_skus['chlid_sku'] = empty($v['sku']) ? trim($master_sku.$chlid_sku_suffix) : trim($v['sku']);
            $chlid_sku_suffix = '';
            // 验证子sku是否已存在
            $count = $this->productAttrVariousService->count(['chlid_sku'=>$attr_skus['chlid_sku']]);
            if($count) ApiUtil::abort('子sku对应的变体已存在');
            // 插入子SKU
            $attr_skus['product_id'] = $pid;
            $attr_skus['price'] = !empty($v['price'])?floatval($v['price']):0;
            $attr_skus['supplier_id'] = $v['supplier_id'];
            $attr_skus['weight'] = $v['weight'];
            $attr_skus['image_path'] = $v['image_path'];
            $attr_sku_id = $this->productAttrVariousService->insertGetId($attr_skus);
            // 插入变体和属性的关联表
            $attr_various['attr_sku_id'] = $attr_sku_id;
            $attr_various['attr_value_id'] = implode(',', $attr_value_link[$k]);
            $this->productAttrVariousValueLinkService->insertGetId($attr_various);
        }
    }

    // 删除变体属性
    function delSkus(string $ids='')
    {
        if(empty($ids)) return false;
        $whereIn = array();
        $whereIn[0] = 'product_id';
        $whereIn[1] = explode(',', $ids);
        $this->productAttrNameService->deleteBatch($whereIn);
        $this->productAttrValueService->deleteBatch($whereIn);
        $linkIds = $this->productAttrVariousService->select([],['id'],$whereIn)->column('id');
        $this->productAttrVariousService->deleteBatch($whereIn);
        $this->productAttrVariousValueLinkService->deleteBatch(['attr_sku_id',$linkIds]);
    }

    function excelHeader(){
        $header = array(
            array('column' => 'ptime', 'name' => '日期', 'width' => 15,'color' => 'Red'),
            array('column' => 'name', 'name' => '产品名称', 'width' => 30),
            array('column' => 'image', 'name' => '图片', 'width' => 10,'dataType'=>'image'),
            array('column' => 'sku', 'name' => 'SKU', 'width' => 15),
            array('column' => 'category_id', 'name' => '分类', 'width' => 15),
            array('column' => 'crowd', 'name' => '人群', 'width' => 10),
            array('column' => 'manufacturer_number', 'name' => '厂家货号', 'width' => 15),
            array('column' => 'purchase_price', 'name' => '采购价', 'width' => 10),
            array('column' => 'freight', 'name' => '运费', 'width' => 10),
            array('column' => 'weight', 'name' => '重量-g', 'width' => 10),
            array('column' => 'moq', 'name' => '起订量', 'width' => 10),
            array('column' => 'recommend_reason', 'name' => '推荐理由', 'width' => 15),
            array('column' => 'product_grade', 'name' => '产品等级', 'width' => 15),
            array('column' => 'remark', 'name' => '备注', 'width' => 15),
            array('column' => 'competing_product_link', 'name' => '竞品链接', 'width' => 30,'dataType'=>'url'),
            array('column' => 'source_link', 'name' => '货源链接', 'width' => 30,'dataType'=>'url'),
            array('column' => 'charged_str', 'name' => '是否带电', 'width' => 15),
//            array('column' => 'variant', 'name' => '变体', 'width' => 30),
        );
        return $header;
    }
}
